<template>
  <div class="app-container">
    <el-form ref="form" :model="params">
      <div class="params-form params-form-gray">
        <el-form-item label="报销单ID">
          <el-input v-model="params.billNoteId" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="关键词">
          <el-input v-model="params.description" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="创建时间">
          <el-date-picker
            v-model="params.date"
            type="daterange"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item>
          <el-button :icon="Search" type="primary" @click="init">查询</el-button>
          <el-button :icon="RefreshRight" plain type="primary" @click="reset">重置</el-button>
        </el-form-item>
      </div>
    </el-form>
    <div class="table-add">
      <el-button type="primary" :icon="Plus" @click="openDrawer">新建</el-button>
    </div>
    <div class="table" :style="{ '--colums': 7 }">
      <div class="table-head">
        <div>报销单ID</div>
        <div>描述</div>
        <div>关联合同</div>
        <div>创建时间</div>
        <div>报销金额</div>
        <div>状态</div>
        <div>操作</div>
      </div>
      <el-empty v-if="!data.length"></el-empty>
      <el-scrollbar max-height="calc(100vh - 450px)">
        <div class="row" v-for="item in data" :key="item.billNoteId">
          <div>{{ item.billNoteId }}</div>
          <div class="desc">{{ item.description }}</div>
          <div>{{ item.contractName || "空" }}</div>
          <div>{{ item.createTime || "--" }}</div>
          <div>{{ item.money }}</div>
          <div>
            <el-tag :type="statusList[item.status].color">{{ statusList[item.status].title }}</el-tag>
          </div>
          <div>
            <el-button type="primary" link @click="openDrawer(item)">详情</el-button>
            <el-button type="primary" link @click="openDel(item)">删除</el-button>
          </div>
        </div>
      </el-scrollbar>
    </div>
    <div class="pagination">
      <el-pagination
        v-model:current-page="query.current"
        v-model:page-size="query.size"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="init"
        @current-change="init"
      />
    </div>
    <el-drawer v-model="visible" :with-header="false" @close="close">
      <div class="drawer-content">
        <div class="title-box">
          <custom-title :title="isNew ? '新建报销单' : '报销单详情'" />
          <el-icon @click="visible = false">
            <Close />
          </el-icon>
        </div>
        <div :class="{ 'params-form-gray': !isNew }" v-if="visible">
          <el-form :model="addForm" ref="addFormRef" :rules="isNew ? rules : {}" label-width="auto">
            <el-form-item label="报销分类" prop="billCategoryId">
              <el-cascader
                v-if="isNew"
                style="flex: 1"
                placeholder="请选择分类"
                :props="{ label: 'billCategoryName', value: 'billCategoryId' }"
                :options="loanTree"
                v-model="addForm.billCategoryId"
                @change="getForm"
              />
              <div class="preview" v-else>{{ addForm.billCategoryName }}</div>
            </el-form-item>
            <el-form-item label="报销金额" prop="money">
              <el-input v-if="isNew" placeholder="请输入报销金额" v-model="addForm.money" />
              <div v-else class="preview">{{ addForm.money }}</div>
            </el-form-item>
            <el-form-item label="支付账号" prop="partnerAccountId">
              <div class="form-item-space">
                <template v-if="isNew">
                  <el-select v-model="addForm.partnerAccountId">
                    <template #prefix>
                      <el-select
                        v-model="payType"
                        style="width: 100px; border-right: 1px solid #d7d8e0"
                        @change="addForm.partnerAccountId = ''"
                      >
                        <el-option
                          v-for="item in payTypeList"
                          :label="item.dictName"
                          :value="item.dictName"
                          :key="item.dictId"
                        ></el-option>
                      </el-select>
                    </template>
                    <el-option
                      v-for="item in accountList.filter(v => v.dictName == payType)"
                      :value="item.partnerAccountId"
                      :key="item.partnerAccountId"
                      :label="item.account"
                    ></el-option>
                  </el-select>
                  <el-button type="primary" link @click="openAddAccount">新建</el-button>
                </template>
                <div v-else class="preview">
                  {{ splicing([addForm.payType, addForm.partnerAccountName, addForm.accountName], " - ") }}
                </div>
              </div>
            </el-form-item>
            <el-form-item label="合作方" prop="partnerIds">
              <el-select-v2
                v-if="isNew"
                v-model:model-value="addForm.partnerIds"
                filterable
                remote
                :remote-method="remoteMethodPartner"
                clearable
                :options="options"
                :props="props"
                placeholder="请输入名称"
                @change="changePartner"
              />
              <div v-else class="preview">{{ addForm.partnerName || "--" }}</div>
            </el-form-item>
            <el-form-item label="关联合同" prop="contractId" v-if="currentPartner.type == 1">
              <el-select-v2
                v-if="isNew"
                v-model:model-value="addForm.contractId"
                filterable
                remote
                :remote-method="remoteMethodContract"
                clearable
                :options="contractOptions"
                :props="contractProps"
                placeholder="请输入名称"
              />
              <div v-else class="preview">{{ addForm.contractName || "--" }}</div>
            </el-form-item>
            <el-form-item label="报销描述" prop="description">
              <el-input v-if="isNew" type="textarea" v-model="addForm.description" placeholder="请输入报销描述" />
              <div v-else class="preview">{{ addForm.description }}</div>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <el-divider style="margin: 0" v-if="newFormItem.length"></el-divider>
      <div class="drawer-content">
        <div :class="{ 'oa-form': true, 'params-form-gray': true, disable: !isNew }" v-if="newFormItem.length">
          <form-render ref="formRenderRef" :forms="newFormItem" v-model="formData" />
        </div>
      </div>
      <template #footer v-if="isNew">
        <div class="footer-btn">
          <el-button @click="visible = false">取消</el-button>
          <el-button type="primary" @click="confirm" :disabled="isUploadFile">确定</el-button>
        </div>
      </template>
    </el-drawer>
    <el-dialog v-model="accountVisible" width="400" center align-center :show-close="false" @close="closeAccount">
      <template #title>
        <custom-title title="新建支付账号" />
      </template>
      <el-form :model="accountForm" label-width="auto" ref="accountFormRef" :rules="accountRules">
        <el-form-item label="支付方式" prop="dictId">
          <el-select-v2
            v-model:model-value="accountForm.dictId"
            filterable
            remote
            :remote-method="remoteMethod"
            clearable
            :options="payTypeList"
            :props="{ label: 'dictName', value: 'dictId' }"
            placeholder="请输入名称"
          />
        </el-form-item>
        <el-form-item label="账号" prop="account">
          <el-input v-model="accountForm.account" placeholder="请输入账号" />
        </el-form-item>
        <el-form-item label="开户银行" prop="bankName">
          <el-input v-model="accountForm.bankName" placeholder="请输入开户银行" />
        </el-form-item>
        <el-form-item label="户名" prop="accountName">
          <el-input v-model="accountForm.accountName" placeholder="请输入户名" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="footer-btn">
          <el-button @click="accountVisible = false">取消</el-button>
          <el-button type="primary" @click="addAccount">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog v-model="delVisible" width="400" center align-center :show-close="false">
      <div class="sure">
        <div>
          <el-icon>
            <Warning />
          </el-icon>
        </div>
        <span>此报销单将被删除，是否继续？</span>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="delVisible = false">取 消</el-button>
          <el-button type="primary" @click="delItem">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, toRefs } from "vue";
import { Search, RefreshRight, Plus } from "@element-plus/icons-vue";
import {
  del,
  getFormDetail,
  getDetail,
  getFormData,
  getAccount as getAccountList,
  getLoanTree,
  addAccount as add
} from "@/apis/oa/index";
import { getList, addOaReimbursed, getPartner, getContractList } from "@/apis/oa/reimbursed";
import { getTargetKey } from "@/utils/tree";
import { ElMessage } from "element-plus";
import { payTypeDict } from "@/apis/dict/dict";
import { type } from "@/utils/config";
import { splicing } from "@/utils";
import useIsUploadFile from "@/hooks/useIsUploadFile";

const props = {
  label: "name",
  value: "partnerId"
};
const options = ref([]);
const accountForm = ref({});
const accountVisible = ref(false);
const visible = ref(false);
const statusList = {
  1: { title: "审批中", color: "warning" },
  2: { title: "处理中", color: "primary" },
  3: { title: "已处理", color: "success" },
  4: { title: "未通过", color: "danger" }
};
const addFormRef = ref(null);
const formRenderRef = ref(null);
const accountFormRef = ref(null);
const formData = ref({});
const formItemsData = ref([]);
const params = ref({});
const query = ref({
  current: 1,
  size: 10
});
const payType = ref("");
const total = ref(0);
const isNew = ref(false);
const addForm = ref({});
const data = ref([]);
const accountList = ref([]);
const shieldArr = ["金额", "分类", "费用描述", "关联合作方"];
const newFormItem = computed(() => (formItemsData.value ? formItemsData.value.filter(v => !shieldArr.includes(v.title)) : []));
const { isUploadFile, isGetUploadFileUrl } = toRefs(useIsUploadFile(newFormItem, formData));
const openDrawer = async item => {
  if (item.billNoteId) {
    isNew.value = false;
    const res = await getDetail(item.billNoteId);
    addForm.value = res.data;
    const formRes = await getFormDetail(res.data.flowInstanceId);
    formData.value = formRes.data.formData;
    formItemsData.value = formRes.data.formItems?.map(v => ({ ...v, props: { ...v.props, disabled: true } }));
  } else {
    isNew.value = true;
  }
  visible.value = true;
};
const openAddAccount = () => {
  payTypeList.value = [];
  accountVisible.value = true;
};
const closeAccount = () => {
  accountFormRef.value.resetFields();
};
const accountRules = {
  account: [
    { required: true, message: "请输入账号", trigger: "blur" },
    { max: 25, message: "开户银行不能超过25个字符", trigger: "blur" }
  ],
  dictId: [{ required: true, message: "请选择支付方式", trigger: "blur" }],
  accountName: [{ max: 20, message: "户名不能超过20个字符", trigger: "blur" }],
  bankName: [{ max: 20, message: "开户银行不能超过20个字符", trigger: "blur" }]
};
const rules = {
  billCategoryId: [{ required: true, message: "请选择报销分类", trigger: "change" }],
  money: [
    { required: true, message: "请输入报销金额", trigger: "blur" },
    { pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: "请输入正确的金额", trigger: "blur" }
  ],
  partnerAccountId: [{ required: true, message: "请选择支付账号", trigger: "change" }],
  description: [
    { required: true, message: "请输入报销描述", trigger: "blur" },
    { max: 300, message: "报销描述不能超过300个字符", trigger: "blur" }
  ]
};
const delVisible = ref(false);
const delId = ref("");
/**
 * 打开删除弹窗
 */
const openDel = item => {
  delId.value = item.billNoteId;
  delVisible.value = true;
};
const close = () => {
  addForm.value = {};
  formItemsData.value = [];
  formData.value = {};
  addFormRef.value?.resetFields();
  formRenderRef.value?.resetForm();
  accountVisible.value = false;
  payType.value = "";
};
const reset = () => {
  params.value = {};
  init();
};
const delItem = async () => {
  const res = await del(1, delId.value);
  if (res.code == 200) {
    init();
    ElMessage.success("删除成功");
    delVisible.value = false;
  }
};
const contractOptions = ref([]);
const contractProps = {
  value: "contractId",
  label: "title"
};
/**
 * 查询合作方
 */
const remoteMethodPartner = async value => {
  if (value.trim() == "") {
    options.value = [];
    return;
  }
  const res = await getPartner(value || undefined);
  options.value = res.data.map(v => ({ ...v, name: type[v.type] + " : " + v.name }));
};
const remoteMethodContract = async value => {
  const res = await getContractList({
    customerId: currentPartner.value.thirdTag,
    contractName: value
  });
  contractOptions.value = res.data.map(v => ({ ...v, name: type[v.type] + " : " + v.name }));
};
const payTypeList = ref([]);

const remoteMethod = async dictName => {
  const res = await payTypeDict({ status: 1, dictName });
  payTypeList.value = res.data;
};
const getForm = async value => {
  let formId = "";
  const traverse = (tree, billCategoryId) => {
    for (let item of tree) {
      if (item.billCategoryId == billCategoryId) {
        formId = item.formId;
        return;
      } else if (item.children && item.children.length) {
        traverse(item.children, billCategoryId);
      }
    }
  };
  traverse(loanTree.value, value[value.length - 1]);
  try {
    const res = await getFormData(formId);
    formItemsData.value = JSON.parse(res.data.formItems);
  } catch (error) {}
};
const init = async () => {
  let startCreateTime = "";
  let endCreateTime = "";
  if (params.value.date) {
    startCreateTime = params.value.date[0] + " " + "00:00:00";
    endCreateTime = params.value.date[1] + " " + "23:59:59";
  } else {
    startCreateTime = undefined;
    endCreateTime = undefined;
  }
  const res = await getList(query.value, { ...params.value, startCreateTime, endCreateTime });
  total.value = res.data.total;
  data.value = res.data.list;
};
const loanTree = ref([]);
const getTree = async () => {
  const res = await getLoanTree();
  loanTree.value = res.data.filter(v => v.type == 1);
};
const addAccount = () => {
  accountFormRef.value.validate(async valid => {
    if (valid) {
      const res = await add({ ...accountForm.value, status: 1 });
      if (res.code == 200) {
        accountVisible.value = false;
        ElMessage.success("添加成功");
        getAccount();
      }
    }
  });
};
const currentPartner = ref({});
/**
 * 变更合作方
 */
const changePartner = value => {
  currentPartner.value = options.value.find(v => v.partnerId == value);
};

const verify = () => {
  let arr = [];
  arr.push(
    new Promise(resolve => {
      addFormRef.value.validate(valid => {
        resolve(valid);
      });
    })
  );
  if (newFormItem.value.length) {
    arr.push(
      new Promise(resolve => {
        formRenderRef.value.submitForm(valid => {
          resolve(valid);
        });
      })
    );
  }
  return Promise.all(arr);
};
const confirm = async () => {
  if ((await verify()).every(v => v)) {
    formItemsData.value.forEach(v => {
      if (v.title == "金额") {
        formData.value[v.id] = addForm.value.money;
      }
      if (v.title == "分类") {
        formData.value[v.id] = getTargetKey(
          loanTree.value,
          "billCategoryId",
          "billCategoryName",
          addForm.value.billCategoryId[0]
        );
      }
      if (v.title == "费用描述") {
        formData.value[v.id] = addForm.value.description;
      }
      if (v.title == "关联合作方") {
        formData.value[v.id] = getTargetKey(options.value, "partnerId", "name", addForm.value.partnerIds).split(" : ")[1];
      }
    });
    try {
      const contractName = contractOptions.value.find(v => v.contractId == addForm.value.contractId)?.title;
      await addOaReimbursed({
        ...addForm.value,
        fromData: formData.value,
        billCategoryId: addForm.value.billCategoryId[addForm.value.billCategoryId.length - 1],
        partnerIds: addForm.value.partnerIds ? [addForm.value.partnerIds] : undefined,
        contractName
      });
      init();
      ElMessage.success("添加成功");
      visible.value = false;
    } catch (error) {}
  }
};
const getAccount = async () => {
  const res = await getAccountList();
  accountList.value = res.data
    ? res.data.map(v => ({ ...v, account: splicing([v.dictName, v.account, v.accountName], " - ") }))
    : [];
};
onMounted(() => {
  init();
  getTree();
  getAccount();
  remoteMethod();
});
</script>

<style lang="scss" scoped>
@import "../index.scss";
</style>
